# tts.py - 简化修复版本（优先保证播放）
import base64
import json
import os
import ssl
import wave
import hmac
import hashlib
import time
from urllib.parse import urlencode
from datetime import datetime
from time import mktime
from wsgiref.handlers import format_date_time
from config import SPARK_APPID, SPARK_APIKey, SPARK_APISecret
import logging

logger = logging.getLogger(__name__)

# 检查WebSocket可用性
try:
    import websocket

    WEBSOCKET_AVAILABLE = True
    logger.info("WebSocket模块可用")
except ImportError:
    WEBSOCKET_AVAILABLE = False
    logger.warning("WebSocket模块不可用")

OUTPUT_PCM_PATH = "demo.pcm"
OUTPUT_WAV_PATH = "demo.wav"


def clean_text_simple(text):
    """简单的文本清理，避免过度处理"""
    if not text:
        return ""

    # 只做最基本的清理
    text = text.strip()

    # 替换明显有问题的重复词汇
    text = text.replace("比如比如", "比如")
    text = text.replace("具体具体", "具体")
    text = text.replace("参与的参与", "参与")
    text = text.replace("作为作为", "作为")

    # 限制长度
    if len(text) > 300:
        text = text[:300] + "。"

    return text


def create_tts_url():
    """创建TTS WebSocket URL"""
    try:
        url = 'wss://tts-api.xfyun.cn/v2/tts'
        date = format_date_time(mktime(datetime.now().timetuple()))
        signature_origin = f"host: ws-api.xfyun.cn\ndate: {date}\nGET /v2/tts HTTP/1.1"
        sign_sha = hmac.new(SPARK_APISecret.encode(), signature_origin.encode(), digestmod=hashlib.sha256).digest()
        signature_sha = base64.b64encode(sign_sha).decode('utf-8')
        authorization_origin = f'api_key="{SPARK_APIKey}", algorithm="hmac-sha256", headers="host date request-line", signature="{signature_sha}"'
        authorization = base64.b64encode(authorization_origin.encode()).decode('utf-8')

        return url + '?' + urlencode({
            "authorization": authorization,
            "date": date,
            "host": "ws-api.xfyun.cn"
        })
    except Exception as e:
        logger.error(f"创建TTS URL失败: {e}")
        return None


def pcm_to_wav(pcm_path, wav_path):
    """将PCM文件转换为WAV文件"""
    try:
        if not os.path.exists(pcm_path):
            logger.error(f"PCM文件不存在: {pcm_path}")
            return False

        with open(pcm_path, 'rb') as pcmfile:
            pcmdata = pcmfile.read()

        if len(pcmdata) == 0:
            logger.error("PCM文件为空")
            return False

        with wave.open(wav_path, 'wb') as wavfile:
            wavfile.setnchannels(1)
            wavfile.setsampwidth(2)
            wavfile.setframerate(16000)
            wavfile.writeframes(pcmdata)

        logger.info(f"✅ PCM转WAV成功: {wav_path}")
        return True
    except Exception as e:
        logger.error(f"PCM转WAV失败: {e}")
        return False


def synthesize_and_play(text):
    """
    语音合成主函数 - 简化版本
    """
    if not text or len(text.strip()) == 0:
        logger.warning("文本为空，跳过语音合成")
        return False

    # 简单清理文本
    cleaned_text = clean_text_simple(text)
    logger.info(f"🔄 处理文本: {cleaned_text[:50]}...")

    if not WEBSOCKET_AVAILABLE:
        logger.error("WebSocket不可用，跳过语音合成")
        return False

    try:
        url = create_tts_url()
        if not url:
            logger.error("无法创建TTS URL")
            return False

        # 全局变量存储状态
        synthesis_complete = False
        synthesis_error = None
        audio_received = False

        def on_message(ws, message):
            nonlocal synthesis_complete, synthesis_error, audio_received
            try:
                msg = json.loads(message)
                logger.debug(f"收到消息: {msg}")

                if "data" in msg and "audio" in msg["data"]:
                    audio = base64.b64decode(msg["data"]["audio"])

                    # 写入PCM文件（追加模式）
                    with open(OUTPUT_PCM_PATH, 'ab') as f:
                        f.write(audio)

                    audio_received = True
                    logger.debug(f"收到音频数据: {len(audio)} bytes")

                    # 检查是否完成
                    if msg["data"]["status"] == 2:  # 合成完成
                        logger.info("✅ TTS合成完成")
                        synthesis_complete = True
                        ws.close()

                elif "data" in msg:
                    logger.debug(f"收到状态消息: {msg['data']}")
                else:
                    logger.warning(f"未知消息格式: {msg}")

            except Exception as e:
                logger.error(f"处理TTS消息失败: {e}")
                synthesis_error = str(e)
                ws.close()

        def on_error(ws, error):
            nonlocal synthesis_error
            logger.error(f"TTS WebSocket错误: {error}")
            synthesis_error = str(error)

        def on_open(ws):
            try:
                # 清理旧的PCM文件
                if os.path.exists(OUTPUT_PCM_PATH):
                    os.remove(OUTPUT_PCM_PATH)
                    logger.debug("清理旧PCM文件")

                # 🔥 使用最简单的TTS参数
                data = {
                    "common": {
                        "app_id": SPARK_APPID
                    },
                    "business": {
                        "aue": "raw",
                        "auf": "audio/L16;rate=16000",
                        "vcn": "xiaoyan",  # 使用稳定的发音人
                        "tte": "utf8"
                    },
                    "data": {
                        "status": 2,
                        "text": str(base64.b64encode(cleaned_text.encode('utf-8')), 'utf-8')
                    }
                }

                logger.info(f"🔊 发送TTS请求: {cleaned_text[:30]}...")
                ws.send(json.dumps(data))

            except Exception as e:
                logger.error(f"发送TTS请求失败: {e}")
                synthesis_error = str(e)
                ws.close()

        # 创建WebSocket连接
        ws = websocket.WebSocketApp(
            url,
            on_open=on_open,
            on_message=on_message,
            on_error=on_error
        )

        logger.info("🔄 开始语音合成...")

        # 运行WebSocket
        ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE})

        # 检查结果
        if synthesis_error:
            logger.error(f"❌ 语音合成失败: {synthesis_error}")
            return False

        if not synthesis_complete:
            logger.error("❌ 语音合成未完成")
            return False

        if not audio_received:
            logger.error("❌ 未收到音频数据")
            return False

        # 转换为WAV格式
        if os.path.exists(OUTPUT_PCM_PATH):
            pcm_size = os.path.getsize(OUTPUT_PCM_PATH)
            logger.info(f"📁 PCM文件大小: {pcm_size} bytes")

            if pcm_size > 0:
                if pcm_to_wav(OUTPUT_PCM_PATH, OUTPUT_WAV_PATH):
                    wav_size = os.path.getsize(OUTPUT_WAV_PATH)
                    logger.info(f"✅ 语音文件生成成功: {OUTPUT_WAV_PATH}, 大小: {wav_size} bytes")
                    return True
                else:
                    logger.error("❌ PCM转WAV失败")
                    return False
            else:
                logger.error("❌ PCM文件为空")
                return False
        else:
            logger.error("❌ PCM文件不存在")
            return False

    except Exception as e:
        logger.error(f"❌ 语音合成异常: {e}")
        return False


def get_audio_file_path():
    """获取生成的音频文件路径"""
    if os.path.exists(OUTPUT_WAV_PATH):
        return OUTPUT_WAV_PATH
    return None


def cleanup_audio_files():
    """清理临时音频文件"""
    try:
        if os.path.exists(OUTPUT_PCM_PATH):
            os.remove(OUTPUT_PCM_PATH)
        if os.path.exists(OUTPUT_WAV_PATH):
            os.remove(OUTPUT_WAV_PATH)
        logger.info("🧹 音频文件已清理")
    except Exception as e:
        logger.warning(f"清理音频文件失败: {e}")


def test_tts():
    """测试语音合成功能"""
    test_text = "你好，欢迎参加面试。"
    logger.info("🧪 开始测试语音合成...")

    success = synthesize_and_play(test_text)
    if success:
        logger.info("✅ 语音合成测试成功")
        if os.path.exists(OUTPUT_WAV_PATH):
            file_size = os.path.getsize(OUTPUT_WAV_PATH)
            logger.info(f"📁 生成的文件大小: {file_size} bytes")
        return True
    else:
        logger.error("❌ 语音合成测试失败")
        return False


# 快速测试函数
def quick_test():
    """快速测试TTS功能"""
    print("🧪 快速TTS测试")
    print("=" * 30)

    # 检查配置
    if not SPARK_APPID or SPARK_APPID == "your_spark_app_id":
        print("❌ SPARK_APPID未配置")
        return False

    print(f"✅ 配置检查通过")
    print(f"📱 APPID: {SPARK_APPID}")

    # 测试简单文本
    test_text = "测试语音播放"
    print(f"🔊 测试文本: {test_text}")

    try:
        success = synthesize_and_play(test_text)

        if success:
            print("✅ 语音合成成功")
            audio_path = get_audio_file_path()
            if audio_path:
                size = os.path.getsize(audio_path)
                print(f"📁 音频文件: {audio_path} ({size} bytes)")

                # 尝试播放
                if os.name == 'nt':  # Windows
                    os.system(f'start {audio_path}')
                print("🔊 已尝试播放音频")
                return True
            else:
                print("❌ 音频文件不存在")
                return False
        else:
            print("❌ 语音合成失败")
            return False

    except Exception as e:
        print(f"❌ 测试异常: {e}")
        return False


if __name__ == "__main__":
    import sys

    if len(sys.argv) > 1 and sys.argv[1] == "test":
        quick_test()
    else:
        print("🔧 TTS模块")
        print("使用方法: python tts.py test")
        print("或导入模块: from tts import synthesize_and_play")